<?php

namespace Core;

use App\Facades\Log;
use App\Facades\Router;
use Core\Database\DatabaseConnection;

class Framework
{
    protected $basePath;
    protected $storagePath;
    protected $container;
    protected $providers;

    public function __construct($basePath)
    {
        $this->basePath = $basePath;
        // 创建容器
        $this->container = Container::getInstance();

        // 设置容器实例到门面
        Facade::setContainer($this->container);

        // 将框架自身绑定到容器
        $this->container->instance('app', $this);
        $this->container->instance(Container::class, $this->container);

        // 加载配置
        $this->loadConfig();

        // 注册基础服务
        $this->registerBaseServices();

        // 注册服务提供者
        $this->registerServiceProviders();
    }

    protected function loadConfig()
    {
        // 加载主配置
        $configFile = __DIR__ . '/../config/config.php';
        if (file_exists($configFile)) {
            $config = require_once($configFile);
            $this->container->instance('config', $config);
        }

        $providersFile = __DIR__  . '/../config/providers.php';
        if (file_exists($providersFile)) {
            $this->providers = require_once($providersFile);
        }
    }
    
    protected function registerBaseServices()
    {
        // 绑定数据库服务
        $this->container->singleton('connection', function () {
            $config = config('database');
            return new DatabaseConnection($config);
        });
    }

    protected function registerServiceProviders()
    {
        foreach ($this->providers as $provider) {
            $providerInstance = new $provider($this->container);
            $providerInstance->register();

            // 如果提供者有boot方法，稍后调用
            if (method_exists($providerInstance, 'boot')) {
                $providerInstance->boot();
            }
        }
    }

    public function run()
    {
        try {
            // 分发路由
            Router::dispatch();
        } catch (\Exception $e) {
            Log::error($e->getMessage() . "\n" . $e->getTraceAsString());
            throw $e;
        }
    }

    // 获取容器实例
    public function getContainer()
    {
        return $this->container;
    }

    public function basePath($path = '')
    {
        return $this->joinPaths($this->basePath, $path);
    }

    function joinPaths($basePath, $path)
    {
        return $basePath . DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR);
    }

    public function storagePath($path = '')
    {
        return $this->joinPaths($this->storagePath ?: $this->basePath('storage'), $path);
    }
}
